package com.yx.coredata.utils;

import org.apache.tools.zip.ZipEntry;
import org.apache.tools.zip.ZipOutputStream;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.zip.ZipInputStream;


public class CompressorUtils {

    private static final Logger log = LoggerFactory.getLogger(CompressorUtils.class);

    private static final int BUFFEREDSIZE = 1024;


    /**
     * 解压zip或者rar包的内容到指定的目录下，可以处理其文件夹下包含子文件夹的情况
     *
     * @param zipFile_     要解压的zip或者rar包文件
     * @param outFile 解压后存放的目录
     */
    public static synchronized void unzip(File zipFile_, File outFile)
            throws IOException {
        String rootPath = outFile.getPath() + "/";

        InputStream inputStream = null;
        OutputStream outputStream = null;

        java.util.zip.ZipEntry zipEntry = null;
        java.util.zip.ZipFile file = new java.util.zip.ZipFile(zipFile_);
        ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipFile_));

        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
            log.error("解压缩: " + rootPath + zipEntry.getName() + " 文件。");
            outFile = new File(rootPath + File.separator + zipEntry.getName()) ;

            if(!outFile.getParentFile().exists()) {
                outFile.getParentFile().mkdir();
            }

            if(!outFile.exists()) {
                if(outFile.isDirectory()||zipEntry.isDirectory()) {
                    outFile.mkdir();
                }else{
                    outFile.createNewFile();
                }
            }

            // 获取每个实体的输入流
            inputStream = file.getInputStream(zipEntry);
            if (outFile.isDirectory()) {
                continue;
            } else {
                outputStream = new FileOutputStream(outFile);
                int len = 0;
                byte[] buf = new byte[BUFFEREDSIZE];
                while ((len = inputStream.read(buf)) != -1) {
                    outputStream.write(buf, 0, len);
                }
                inputStream.close();
                outputStream.close();
                zipEntry.clone();
            }
        }
        zipInputStream.close();
    }

    public static void createZip(String zipPath,Object... sourcePath) {
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        try {
            fos = new FileOutputStream(zipPath);
            zos = new ZipOutputStream(fos);
            zos.setEncoding("GBK");     // 解决中文乱码
            for (Object s : sourcePath) {
                writeZip(new File(s.toString()), "", zos);
            }

        } catch (FileNotFoundException e) {
            log.error("创建ZIP文件失败",e);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (zos != null) {
                    zos.close();
                }
            } catch (IOException e) {
                log.error("创建ZIP文件失败",e);
            }

        }
    }

    private static void writeZip(File file, String parentPath, ZipOutputStream zos) throws IOException {
        if(file.exists()){
            //处理文件夹
            if(file.isDirectory()){
                parentPath+=file.getName()+File.separator;
                File [] files=file.listFiles();
                if (files.length == 0 ) {
                    ZipEntry ze = new ZipEntry(parentPath + "/");
                    zos.putNextEntry(ze);
                    zos.setEncoding("GBK");
                    zos.closeEntry();
                    return;
                }
                for(File f:files){
                    writeZip(f, parentPath, zos);
                }

            }else{
                FileInputStream fis=null;
                DataInputStream dis=null;
                try {


                    fis=new FileInputStream(file);
                    dis=new DataInputStream(new BufferedInputStream(fis));

                    ZipEntry ze = new ZipEntry(parentPath + file.getName());
                    zos.putNextEntry(ze);
                    //添加编码，如果不添加，当文件以中文命名的情况下，会出现乱码
                    // ZipOutputStream的包一定是apache的ant.jar包。JDK也提供了打压缩包，但是不能设置编码
                    zos.setEncoding("GBK");
                    byte [] content=new byte[1024];
                    int len;
                    while((len=fis.read(content))!=-1){
                        zos.write(content,0,len);
                        zos.flush();
                    }
                } catch (FileNotFoundException e) {
                    log.error("创建ZIP文件失败",e);
                } catch (IOException e) {
                    log.error("创建ZIP文件失败",e);
                }finally{
                    try {
                        if(dis!=null){
                            dis.close();
                        }
                    }catch(IOException e){
                        log.error("创建ZIP文件失败",e);
                    }
                }
            }
        }
    }

    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("D:/ziptest/files_export_2017_06_14_17_31_22");
//        list.add("f:\\testzip\\2");


        CompressorUtils.createZip("D:/ziptest/files_export_2017_06_14_17_31_22.zip", list.toArray());
    }
}